/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package servlet;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;
import util.ImageUploadListener;

/**
 *
 * @author Administrator
 */
public class ImageUploadServlet extends HttpServlet {

    String savePath;
    DiskFileItemFactory factory;

    @Override
    public void init() throws ServletException {
        super.init();
        savePath = this.getServletContext().getRealPath("/items");
        // create file upload factory and upload servlet        
        factory = new DiskFileItemFactory();
        // Set factory constraints
        factory.setSizeThreshold(5 * 1024 * 1024);
        factory.setRepository(new File("c:/temp/buffer"));
    }

    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("text/xml");

        PrintWriter out = response.getWriter();
        HttpSession session = request.getSession();
        ImageUploadListener listener = null;
        StringBuffer buffy = new StringBuffer();
        long bytesRead = 0, contentLength = 0;

        // Make sure the session has started
        if (session == null) {
            return;
        } else if (session != null) {
            // Check to see if we've created the listener object yet
            listener = (ImageUploadListener) session.getAttribute("LISTENER");
            String error = (String) session.getAttribute("UPLOAD_ERROR");

            if (error != null) {
                buffy.append("<?xml version=\"1.0\" encoding =\"ISO-8859-1\"?>\n");
                buffy.append("<response>\n");
                buffy.append("\t<msg>" + error + "</msg>\n");
                buffy.append("</response>\n");

                session.setAttribute("UPLOAD_ERROR", null);
                session.setAttribute("LISTENER", null);

                out.println(buffy.toString());
                out.flush();
                out.close();
            } else if (listener != null) {
                // Get the meta information
                bytesRead = listener.getBytesRead();
                contentLength = listener.getContentLength();

                buffy.append("<?xml version=\"1.0\" encoding =\"ISO-8859-1\"?>\n");
                buffy.append("<response>\n");
                //buffy.append("\t<read>" + bytesRead + "</read>\n");
                //buffy.append("\t<length>" + contentLength + "</length>\n");

                // Check to see if we're done
                if (bytesRead == contentLength) {
                    buffy.append("\t<finish />\n");
                    buffy.append("\t<img1>" + session.getAttribute("image1") + "</img1>\n");
                    buffy.append("\t<img2>" + session.getAttribute("image2") + "</img2>\n");
                    buffy.append("\t<img3>" + session.getAttribute("image3") + "</img3>\n");

                    // No reason to keep listener in session since we're done
                    session.setAttribute("UPLOAD_ERROR", null);
                    session.setAttribute("LISTENER", null);
                } else {
                    // Calculate the percent complete
                    long percentComplete = ((100 * bytesRead) / contentLength);
                    buffy.append("\t<percent>" + percentComplete + "</percent>\n");
                }
                buffy.append("</response>\n");

                out.println(buffy.toString());
                out.flush();
                out.close();

            } else {
                return;
            }
        }
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        if (!ServletFileUpload.isMultipartContent(request)) {
            return;// impossible??
        }

        /*
         * moved out.. thread safety.???
        // create file upload factory and upload servlet        
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // Set factory constraints
        factory.setSizeThreshold(5 * 1024 * 1024);
        factory.setRepository(new File("c:/temp/buffer"));
         */

        ServletFileUpload upload = new ServletFileUpload(factory);

        // Set overall request size constraint
        upload.setSizeMax(600 * 3 * 1024);

        // set file upload progress listener
        ImageUploadListener listener = new ImageUploadListener();
        HttpSession session = request.getSession(true);
        session.setAttribute("LISTENER", (Object) listener);
        // upload servlet allows to set upload listener
        upload.setProgressListener(listener);

        List uploadedItems = null;
        FileItem fileItem = null;
        // todo:Path to store file on local system

        //clear the images
        clearImages(session);

        try {
            // iterate over all uploaded files
            uploadedItems = upload.parseRequest(request);

            Iterator<FileItem> i = (Iterator<FileItem>) uploadedItems.iterator();

            while (i.hasNext()) {
                fileItem = i.next();

                if (fileItem.isFormField() == false) {
                    if (fileItem.getSize() > 0) {
                        String fieldName = fileItem.getFieldName();
                        String contentType = fileItem.getContentType();
                        if (!(contentType.contains("jpeg") || contentType.contains("gif"))) {
                            //todo: check content type
                            request.getSession(true).setAttribute("UPLOAD_ERROR", "invalid_file_type");
                            clearImages(session);
                            return;
                        }
                        //todo: rename

                        String fileName = FilenameUtils.getName(fileItem.getName());
                        if ("image1".equals(fieldName)) {
                            // Write the uploaded file to the system
                            fileItem.write(new File(savePath, fileName));
                            session.setAttribute("image1", fileName);
                        } else if ("image2".equals(fieldName)) {
                            // Write the uploaded file to the system
                            fileItem.write(new File(savePath, fileName));
                            session.setAttribute("image2", fileName);
                        } else if ("image3".equals(fieldName)) {
                            // Write the uploaded file to the system
                            fileItem.write(new File(savePath, fileName));
                            session.setAttribute("image3", fileName);
                        }
                    }

                }
            }
        } catch (SizeLimitExceededException e) {
            //todo: upload size > max file size
            session.setAttribute("UPLOAD_ERROR", "invalid_file_size");
            clearImages(session);
            e.printStackTrace();
        } catch (FileUploadException e) {
            //todo:usually caused by user cancal the upload
            session.setAttribute("UPLOAD_ERROR", "User Cancel");
            clearImages(session);
            e.printStackTrace();
        } catch (Exception e) {
            //e.printStackTrace();
        }
    }

    public void clearImages(HttpSession s) {
        clearImage(s, "image1");
        clearImage(s, "image2");
        clearImage(s, "image3");
    }

    public void clearImage(HttpSession s, String fileNameInSession) {
        String image = (String) s.getAttribute(fileNameInSession);

        if (image != null) {
            s.setAttribute(fileNameInSession, null);
            File f = new File(savePath, image);
            try {
                f.delete();
            } catch (Exception e) {
            }
        }
    }
}
